import * as THREE from "./threejs/three.module.js";
import { OrbitControls } from "./threejs/jsm/controls/OrbitControls.js";
import { DragControls } from "./threejs/jsm/controls/DragControls.js";
import * as ThreeComm from "./three-comm-new.js";

const CUBE_TYPES = ",Z,L,LQ,DB,"; //长方体类别
const CUBE_TYPE_Z = "Z"; //立柱
const CUBE_TYPE_L = "L"; //梁
const CUBE_TYPE_LQ = "LQ"; //梁墙
const CUBE_TYPE_DB = "DB"; //地板
const CUBE_TYPE_DEF = "Z"; //缺省值

let raycaster = new THREE.Raycaster();
let pointer = new THREE.Vector2();
let orbitControls, dragControls, planeMesh;

const indices = [
  0,
  1,
  2,
  0,
  2,
  3, // 下面
  4,
  5,
  6,
  4,
  6,
  7, // 上面
  // 4, 0, 1, 4, 1, 5,
  8,
  9,
  10,
  8,
  10,
  11, // 前面
  12,
  13,
  14,
  12,
  14,
  15, // 后面
  16,
  17,
  18,
  16,
  18,
  19, // 左面
  20,
  21,
  22,
  20,
  22,
  23, // 右面
];
const uvs = new Float32Array([
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1, // 下面 0,6
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1,
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1, // 前面 12,6
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1, // 后面 18,6
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1, // 左面 24,6
  0,
  0,
  1,
  0,
  1,
  1,
  0,
  1, // 右面 30,6
]);
const groups = [
  {
    start: 0,
    count: 6,
    materialIndex: 0,
  },
  {
    start: 6,
    count: 6,
    materialIndex: 1,
  },
  {
    start: 12,
    count: 6,
    materialIndex: 2,
  },
  {
    start: 18,
    count: 6,
    materialIndex: 3,
  },
  {
    start: 24,
    count: 6,
    materialIndex: 4,
  },
  {
    start: 30,
    count: 6,
    materialIndex: 5,
  },
];

export const initScene = () => {
  let scene, camera, renderer, container;
  // 创建场景
  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x000000);

  container = document.getElementById("container");
  // 创建相机
  camera = new THREE.PerspectiveCamera(
    90,
    window.innerWidth / window.innerHeight,
    0.1,
    10000
  );
  camera.position.x = -300;
  camera.position.y = -500;
  camera.position.z += 900;

  // 创建渲染器
  renderer = new THREE.WebGLRenderer({ antialias: true });
  // 渲染器能够渲染阴影效果
  renderer.shadowMap.enabled = true;
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  // 添加网格辅助器
  const gridHelper = new THREE.GridHelper(5000, 50); // 创建一个200单位的网格，细分为50个方格
  gridHelper.rotation.x = 0.5 * Math.PI;
  //gridHelper.position.y = -150;
  scene.add(gridHelper);

  // 创建一个平面作为底板,用于计算鼠标在水平面的移动
  const planeGeometry = new THREE.PlaneGeometry(5000, 5000);
  const planeMaterial = new THREE.MeshStandardMaterial({
    visible: false,
    wireframe: true,
    // color: 0xffffffff,
    // side: THREE.DoubleSide,
    transparent: true,
    opacity: 0,
  });
  planeMesh = new THREE.Mesh(planeGeometry, planeMaterial);
  planeMesh.position.set(0, 0, 0);
  planeMesh.userData = { type: "plane" };
  scene.add(planeMesh);

  // 方向光
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  directionalLight.position.set(10, 10, 10);

  directionalLight.shadow.mapSize.width = 1024; // default
  directionalLight.shadow.mapSize.height = 1024; // default
  directionalLight.shadow.camera.near = 0.05; // default
  directionalLight.shadow.camera.far = 500; // default
  //将范围调大
  directionalLight.shadow.camera.top = 20; /// 这个是生效的属性
  directionalLight.shadow.camera.right = 20;
  directionalLight.shadow.camera.left = -20;
  directionalLight.shadow.camera.bottom = -20;
  directionalLight.castShadow = true;
  scene.add(directionalLight);

  // 环境光
  const ambientLight = new THREE.AmbientLight(0xffffff, 2);
  scene.add(ambientLight);

  // 添加鼠标控制
  orbitControls = new OrbitControls(camera, renderer.domElement);
  // orbitControls.enableDamping = true; // 使得相机移动更加平滑
  orbitControls.dampingFactor = 0.05; // 阻尼效果

  // window.addEventListener('pointerup', onPointerUp);
  window.addEventListener("resize", onWindowResize, false);

  function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();

    renderer.setSize(window.innerWidth, window.innerHeight);
  }

  render();

  return { scene, camera, renderer, container, orbitControls, planeMesh };

  function render() {
    // 渲染
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }
};

// export function render() {
//     // 渲染
//     requestAnimationFrame(render);
//     renderer.render(scene, camera);
// }

export const addCube = (cubeOpt, hCubes, hCamera, hScene) => {
  //相机不能为空
  if (null == hCamera || typeof hCamera == "undefined") {
    return null;
  }
  //场景不能为空
  if (null == hScene || typeof hScene == "undefined") {
    return null;
  }
  //长方体数据
  var data = cubeOpt.data;
  if (null == data || typeof data == "undefined") {
    cubeOpt.data = {};
    data = cubeOpt.data;
  }
  //长方体坐标转换
  var desc = data.name;
  //长方体坐标点数不少于8个，多余8个只取前面8个
  var points = cubeOpt.points;
  if (
    null == points ||
    typeof points == "undefined" ||
    !(points instanceof Array)
  ) {
    console.log("创建长方体[", desc, "]没有指定顶点");
    return;
  }
  var iPointSize = points.length;
  if (iPointSize != 4 && iPointSize != 8) {
    console.log("创建长方体[", desc, "]顶点数量不为4个或者8个");
    return;
  }
  if (iPointSize == 4) {
    pointsFrom4To8(points, data);
  }
  createCubeGeometry(points, hCubes);

  //创建长方体
  function createCubeGeometry(points, hCubes) {
    //取得长方体颜色
    var data = cubeOpt.data;
    var pColor = null;
    if (null != data && typeof data != "undefined" && data instanceof Object) {
      pColor = data.color;
    }
    if (null == pColor || typeof pColor == "undefined" || pColor == "") {
      pColor = 0xff00ff;
    }
    var material = new THREE.MeshPhongMaterial({
      color: pColor,
      side: THREE.DoubleSide,
    });
    var materials = [
      material,
      material,
      material,
      material,
      material,
      material,
    ];
    var data = cubeOpt.data;
    if (null == data) {
      data = {};
    }
    var hGeometry = new THREE.BufferGeometry();
    var vertices = getCubeFacesVertices(points, desc);
    hGeometry.setAttribute(
      "position",
      new THREE.BufferAttribute(new Float32Array(vertices), 3)
    );
    hGeometry.setIndex(indices);
    hGeometry.setAttribute("uv", new THREE.BufferAttribute(uvs, 2));
    hGeometry.computeVertexNormals();
    var hMesh = new THREE.Mesh(hGeometry, materials);
    hGeometry.groups = groups;
    hMesh.userData = { data: data, points: points };
    if (hCubes instanceof Array) {
      hCubes.push(hMesh);
    }
    hScene.add(hMesh);
  }
  // 将长方体的立方体的8个顶点转变为长方体的面的顶点
  function getCubeFacesVertices(points, desc) {
    if (
      null == points ||
      typeof points == "undefined" ||
      !(points instanceof Array)
    ) {
      return null;
    }
    if (null == desc || typeof desc == "undefined") {
      desc = "";
    }
    var iSize = points.length;
    if (iSize < 8) {
      return null;
    }
    var iIdx;
    var point;
    for (iIdx = 0; iIdx < 8; iIdx++) {
      point = points[iIdx];
      if (null == point) {
        console.log(desc, "长方体顶点存在有空值点");
        return null;
      }
      //检查是否存在坐标非法点
    }
    // 每个面的顶点（顺时针或逆时针）
    const faces = [
      [0, 1, 2, 3], // 底面
      [4, 5, 6, 7], // 顶面
      [0, 1, 5, 4], // 前面
      [2, 3, 7, 6], // 后面
      [0, 3, 7, 4], // 左面
      [1, 2, 6, 5], // 右面
    ];
    // 生成顶点数组
    const facesVertices = [];
    faces.forEach((face) => {
      face.forEach((index) => {
        point = points[index];
        facesVertices.push(point.x);
        facesVertices.push(point.y);
        facesVertices.push(point.z);
      });
    });
    return facesVertices;
  }

  //由平面4个点转变为8个点
  function pointsFrom4To8(points, data) {
    var type = data.type;
    var z1;
    for (var i = 0; i < 4; i++) {
      var point = points[i];
      if (null == point || typeof point == "undefined") {
        continue;
      }
      var x = point.x;
      var y = point.y;
      var z = point.z;
      if (!isNUmber(z)) {
        z = 0;
      }

      z1 = z + 380;
      if (type == "L") {
        z1 = z + 380;
        z = z + 320;
      } else if (type == "DB") {
        z1 = z + 360;
        z = z + 380;
      }
      point.z = z;
      points.push({ x: x, y: y, z: z1 });
    }
  }
  //判别是否为数字
  function isNUmber(num) {
    if (num == null || typeof num == "undefined") {
      return false;
    }
    return /^[0-9]+.?[0-9]*$/.test(num);
  }
};

export const regDrag = (hCubes, camera, renderer, meshDragMarkers) => {
  dragControls = new DragControls(hCubes, camera, renderer.domElement);
  dragControls.mouseButtons = {
    LEFT: THREE.MOUSE.RIGHT,
    MIDDLE: null,
    RIGHT: null,
  };

  // 监听 drag 事件，限制物体只能在 XY 平面上移动
  dragControls.addEventListener("drag", function (event) {
    let hDragObj = event.object;
    // if (hDragObj.userData.type == "dragmarker") {
    //   var userData = ThreeComm.getMessUserData(hDragObj);

    //   var faceIdx = null;
    //   if (!ThreeComm.isEmpty(userData)) {
    //     faceIdx = userData.faceindex;
    //   }
    //   if (!ThreeComm.isNum(faceIdx) || faceIdx < 0 || faceIdx > 5) {
    //     return;
    //   }

    //   var position  = ThreeComm.getMessPosition(hDragObj);
    //   let curSelectedMess = {object: hDragObj.parent.parent}
    //   var points = ThreeComm.getMessPoints(curSelectedMess);

    //   var lambda = getScaleByFace(points,faceIdx,position);

    //   adjustMessByFaceLambda(curSelectedMess,faceIdx,lambda);
    //   updateMessMarkerPoints(curSelectedMess)

    // } else {
      hDragObj.position.z = 0;
    // }
  });

  // 禁用 OrbitControls 在拖动过程中
  dragControls.addEventListener("dragstart", function () {
    if (null == orbitControls || typeof orbitControls == "undefined") {
      return;
    }
    orbitControls.enabled = false; // 禁用 OrbitControls
  });

  // 重新启用 OrbitControls 在拖动结束后
  dragControls.addEventListener("dragend", function () {
    if (null == orbitControls || typeof orbitControls == "undefined") {
      return;
    }
    orbitControls.enabled = true; // 启用 OrbitControls
  });
  
  function adjustMessByFaceLambda(hMess,faceIdx,lambda){
    var hGeometry = ThreeComm.getMessGeometry(hMess);
    if(ThreeComm.isEmpty(hGeometry)){
      console.log('adjustMessByFaceLambda模型不存在')
      return;
    }
    var points = ThreeComm.getMessPoints(hMess);
    if(!ThreeComm.isArray(points)){
      console.log('adjustMessByFaceLambda 取得模型points为空')
      return;
    }
    var edges  = ThreeComm.getFaceEdgePoints(points,faceIdx);
    var iSize  = 0;
    if(ThreeComm.isArray(edges)){
      iSize = edges.length
    }
    var edge,p1,p2,p3;

    console.log('adjustMessByFaceLambda points--',points,'lambda=',lambda,'edge=',edge);
    for(var i=0;i<iSize;i++){
      edge = edges[i]
      p1 = edge[0]
      p2 = edge[1]
      p3 = ThreeComm.getLambdaPoint(p1,p2,lambda)
      adjustMessVertexsByPoint(hMess,p3.idx_,p3,true)
    }
    hGeometry.verticesNeedUpdate = true;
    hGeometry.getAttribute('position').needsUpdate = true
    hGeometry.computeBoundingBox()
  }

  function updateMessMarkerPoints(hMess){
    if(null==hMess || typeof(hMess)=="undefined"){
      return;
    }
  
    let curFaceIdx = hMess.faceIndex;
    if(!ThreeComm.isNum(curFaceIdx)){
      curFaceIdx = null;
    }
    var points = ThreeComm.getMessPoints(hMess);
    //取得各个面以及面的中心点
    for(var faceIdx=0;faceIdx<6;faceIdx++){
      var facePoints = ThreeComm.getMessFacePoints(hMess,faceIdx,points);
      var centerPoint= ThreeComm.getCenterPoint(facePoints);
      ThreeComm.setMarkerPoint(meshDragMarkers,faceIdx,centerPoint);
    }
  }

  function getScaleByFace(points,faceIdx,point){
    if(!ThreeComm.isArray(points)){
        console.log('getScaleByFace points is not Array points=',points,ThreeComm.isArray(points))
        return 0;
      }
      if(!ThreeComm.isNum(faceIdx)){
        console.log('getScaleByFace faceIdx is not Num')
        return 0;
      }
      if(!ThreeComm.isPoint(point)){
        console.log('getScaleByFace point is not Point')
        return 0;
      }
      var p1 = null;
      var p2 = null;
      var faceIdx0 = ThreeComm.getOppositeFaceIdx(faceIdx);
      if(faceIdx0<0){
        return 0;
      }
      var point1 = ThreeComm.getFaceCenterPoint(points,faceIdx0);
      var point2 = ThreeComm.getFaceCenterPoint(points,faceIdx);
      var point3 = ThreeComm.getFootOfPerpendicular(point,point1,point2);
      if(!ThreeComm.isPoint(point3)){
        console.log('getScaleByFace point3 is not Point point3=',point3)
        return 0;
      }
      var dis1 = ThreeComm.twoPointDistance(point1,point2);
      var dis2 = ThreeComm.twoPointDistance(point1,point3);
      console.log('dis1=',dis1,'dis2=',dis2)
      if(dis1==0){
        return 0;
      }
      var result = ThreeComm.accDiv(dis2,dis1); 
      return result;
  }

  function adjustMessVertexsByPoint(hMess,iIdx,opt,bModify){
    if(null==hMess || typeof(hMess)=="undefined"){
      console.log('adjustMessVertexsByPoint 模型为空');
      return null;
    }
    if(null==opt || typeof(opt)=="undefined"){
      console.log('adjustMessVertexsByPoint 修改数据为空');
      return null;
    }
    if(!ThreeComm.isNum(iIdx) || iIdx<0 || iIdx>7){
      console.log('adjustMessVertexsByPoint 修改点序号不是数字、或者不在0..7之间');
      return;
    }
    var hGeometry = ThreeComm.getMessGeometry(hMess);
    if(null==hGeometry || typeof(hGeometry)=="undefined"){
      console.log('adjustMessVertexsByPoint 模型的[Geometry]为空');
      return null;
    }
    if(null==hGeometry.attributes || typeof(hGeometry.attributes)=="undefined"){
      console.log('adjustMessVertexsByPoint 模型的[Geometry.attributes]为空');
      return null;
    }
    if(null==hGeometry.attributes.position || typeof(hGeometry.attributes.position)=="undefined"){
      console.log('adjustMessVertexsByPoint 模型的[Geometry.attributes.position]为空');
      return null;
    }
    if(typeof(bModify)!="boolean"){
      bModify = false;
    }
    var x = opt.x;
    var y = opt.y
    var z = opt.z;

    if(null==x || typeof(x)!="number"){
      x = null;
    }
    if(null==y || typeof(y)!="number"){
      y = null;
    }
    if(null==z || typeof(z)!="number"){
      z = null;
    }
    // 0              1             2            3             4         5
    // 底面          顶面           前面         后面          左面       右面
    // 0  1  2  3    4  5  6  7   8  9  10 11 12  13 14 15 16  17 18 19 20  21 22 23 
    //[0, 1, 2, 3], [4, 5, 6, 7],[0, 1, 5, 4],[2, 3, 7, 6],[0, 3, 7, 4],[1, 2, 6, 5] 
    //            0         1        2        3          4         5         6        7
    var pArr = [[0,8,16],[1,9,20],[2,12,21],[3,13,17],[4,11,19],[5,10,23],[6,15,22],[7,14,18]];
    var myAyy = pArr[iIdx]
    var iSize = myAyy.length;
    var vIdx;
    var iPos;
    var myPointArr = [];
    
    for(var i=0;i<iSize;i++){
      vIdx = myAyy[i]
      iPos = vIdx*3;
      if(null!=x ){
        if(bModify){
          hGeometry.attributes.position.array[iPos  ] = x;
        }else{
          hGeometry.attributes.position.array[iPos  ] += x;
        }
      }
      if(null!=y){
        if(bModify){
          hGeometry.attributes.position.array[iPos+1] = y;
        }else{
          hGeometry.attributes.position.array[iPos+1] += y;
        }
      }
      if(null!=z ){
        if(bModify){
          hGeometry.attributes.position.array[iPos+2] = z;
        }else{
          hGeometry.attributes.position.array[iPos+2] += z;
        }
      }
    }
  }

  return dragControls;
};

export const createDragMarker = (hScene, opt, faceindex) => {
  if (null == opt || typeof opt == "undefined") {
    opt = {};
  }
  const geometry = new THREE.SphereGeometry(3, 32, 16);
  const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
  var dragMarker = new THREE.Mesh(geometry, material);
  dragMarker.visible = false;
  dragMarker.userData = { type: "dragmarker", faceindex };
  hScene.add(dragMarker);
  return dragMarker;
};

const regPicker = () => {
  function onPointerUp(event) {
    // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)

    pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
    pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;

    raycaster.setFromCamera(pointer, camera);

    // 计算物体和射线的焦点
    const intersects = raycaster.intersectObjects(scene.children);
    if (intersects.length > 0) {
      let intersectObj = intersects[0];
      if (intersectObj.uv) {
        console.log("intersectObj--->", intersectObj);
        let optItem,
          faceItem,
          bcheck = false;

        let uvx = intersectObj.uv.x * optparams.size.x;
        let uvy = (1 - intersectObj.uv.y) * optparams.size.y;

        for (let i = 0; i < gOptArry.length; i++) {
          optItem = gOptArry[i];

          if (optItem.faceIdx == intersectObj.face.materialIndex) {
            for (let j = 0; j < optItem.size.length; j++) {
              faceItem = optItem.size[j];
              if (
                faceItem.postion[0].x <= uvx &&
                faceItem.postion[0].y <= uvy &&
                faceItem.postion[0].x + faceItem.postion[1].x >= uvx &&
                faceItem.postion[0].y + faceItem.postion[1].y >= uvy
              ) {
                bcheck = true;
                console.log("拾取第" + (i + 1) + "图片");
                alert(faceItem.title);
                break;
              }
            }
          }
        }

        if (!bcheck) {
          alert(getDatetime());
        }
      }
    }
  }

  window.addEventListener("pointerup", onPointerUp);
};

export default {
  initScene,
  addCube,
  regDrag,
  createDragMarker,
};
